/*
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.inspur.edp.lcm.metadata.core;

import com.inspur.edp.lcm.metadata.common.FileServiceImp;
import com.inspur.edp.lcm.metadata.common.configuration.MavenSettingsLoader;
import com.inspur.edp.lcm.metadata.common.logging.MvnStreamConsumer;
import com.inspur.edp.lcm.metadata.core.exception.MvnExceptionHandler;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.maven.shared.invoker.DefaultInvocationRequest;
import org.apache.maven.shared.invoker.DefaultInvoker;
import org.apache.maven.shared.invoker.InvocationRequest;
import org.apache.maven.shared.invoker.InvocationResult;
import org.apache.maven.shared.utils.cli.CommandLineException;
import org.codehaus.plexus.util.StringUtils;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author zhaoleitr
 */
public class MavenUtilsCore {
    private static final Logger log = LoggerFactory.getLogger(MavenUtilsCore.class);

    private String mavenHomePath;

    private final DefaultInvoker invoker;

    private final InvocationRequest request;

    private final MvnStreamConsumer mvnStreamConsumer;

    private String errorMessage;

    public MavenUtilsCore() {
        invoker = new DefaultInvoker();
        request = new DefaultInvocationRequest();
        mvnStreamConsumer = new MvnStreamConsumer();
    }

    public boolean exeMavenCommand(String javaCodePath, String mavenPath, String goal) {
        initInvoker();

        invoker.setWorkingDirectory(new File(javaCodePath));

        List<String> goals = handleGoul(goal, mavenPath);
        request.setGoals(goals);

        try {
            mvnStreamConsumer.setExceptionString("");
            InvocationResult result = invoker.execute(request);
            int resultNum = result.getExitCode();
            if (resultNum == 0) {
                return true;
            }

            if (resultNum == 1) {
                final String exceptionString = mvnStreamConsumer.getExceptionString();
                if (!exceptionString.isEmpty()) {
                    MvnExceptionHandler mvnExceptionHandler = new MvnExceptionHandler();
                    errorMessage = "";
                    errorMessage = mvnExceptionHandler.handleMessage(exceptionString);
                    errorMessage = errorMessage.isEmpty() ? "maven编译失败，具体错误请参考日志服务[ERROR]部分" : errorMessage;
                }

                CommandLineException executionException = result.getExecutionException();
                if (executionException != null) {
                    throw executionException;
                }
                return false;
            }
        } catch (Exception e) {
            log.error("执行maven命令失败", e);
            e.printStackTrace();
        }
        return false;
    }

    public String getLocalRepository() {
        try {
            String localRepository = MavenSettingsLoader.getSettings().getLocalRepository();
            if (localRepository != null) {
                return localRepository;
            }
        } catch (IOException | XmlPullParserException e) {
            throw new RuntimeException("获取maven本地仓库地址出错，请检查settings.xml配置", e);
        }
        return null;
    }

    public String getErrorMessage() {
        return errorMessage;
    }

    private void initMavenHomePath() {
        if (!StringUtils.isEmpty(mavenHomePath)) {
            return;
        }

        if (System.getenv("MAVEN_HOME") != null) {
            mavenHomePath = System.getenv("MAVEN_HOME");
        } else if (System.getenv("M2_HOME") != null) {
            mavenHomePath = System.getenv("M2_HOME");

            invoker.setMavenHome(new File(System.getenv("M2_HOME")));
        } else {
            String systemPath = System.getenv("Path");
            if (systemPath != null) {
                String[] paths = systemPath.split("\\;");
                for (String path : paths) {
                    if (path.contains("maven")) {
                        mavenHomePath = path.substring(0, path.length() - 4);
                    }
                }
            }
        }
        if (StringUtils.isEmpty(mavenHomePath)) {
            throw new IllegalArgumentException("请配置maven环境变量！MAVEN_HOME=....");
        }
    }

    private List<String> handleGoul(String goal, String mavenPath) {
        List<String> goals = new ArrayList<>();

        StringBuilder goalSb = new StringBuilder(goal);
        String settingsPath = mavenPath + File.separator + "config" + File.separator + "settings.xml";
        FileServiceImp fileService = new FileServiceImp();
        if (fileService.isFileExist(settingsPath)) {
            goalSb.append(" -s ").append(settingsPath);
        } else {
            log.warn("配置文件" + settingsPath + "不存在，使用默认settings.xml配置");
        }

        goals.add(goalSb.toString());
        return goals;
    }

    private void initInvoker() {
        initMavenHomePath();
        invoker.setMavenHome(new File(mavenHomePath));
        request.setOutputHandler(mvnStreamConsumer).setBatchMode(true);
    }
}
